package com.example.lin.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * {@code @className:} CalculateTax
 * {@code @description:} 关税计算工具类
 * {@code @author:} Lin.Gu
 * {@code @date:} 2025/8/20
 */
public class CalculateTax {

    private static final int SCALE = 8;
    private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_UP;

    public static void main(String[] args) {
        //申报金额
        BigDecimal itemValue = new BigDecimal(200.0000);
        //申报重量
        BigDecimal itemWeight = new BigDecimal("230.0000").divide(new BigDecimal("1000"));
        System.out.println("itemValue:" + itemValue + "====itemWeight:" + itemWeight);
        //规则
        String taxRules = "49.6 cents/kg + 19.7%+7.5%+0%+30%";
        BigDecimal taxValue = calculateEachItemTax2(itemValue, itemWeight, taxRules);
        System.out.println("taxValue:" + taxValue);
        System.out.println("taxValue-2:" + taxValue.setScale(2, RoundingMode.HALF_UP));

//        Map<String, String> usTaxMaps = new HashMap<>();
//        usTaxMaps.put("0", "0.05%");
//        usTaxMaps.put("1", "0.05%");
//        usTaxMaps.put("2", "0.1%");
//        BigDecimal taxValueEur = calculateEachItemTaxEur(itemValue, itemWeight,usTaxMaps);
//        System.out.println("taxValueEur:"+taxValueEur);
    }

    /**
     * 通用税率计算公式
     *
     * @param itemValue  申报价值
     * @param itemWeight 申报重量
     * @param taxRules   规则信息 ("+") 隔开拼接
     * @return 税值
     */
    private static BigDecimal calculateEachItemTax2(BigDecimal itemValue, BigDecimal itemWeight, String taxRules) {
        System.out.println("start calculate item tax value  weight  rule " + itemValue + "-" + itemWeight + "-" + taxRules);
        taxRules = taxRules.replaceAll(" ", "");
        BigDecimal totalTax = BigDecimal.ZERO;
        String[] rules = taxRules.toLowerCase().split("\\s*\\+\\s*");

        for (String rule : rules) {
            rule = rule.trim();
            if (rule.isEmpty()) continue;
            // 规则1: Free
            if (rule.equals("free")) {
                continue;
            }
            // 规则2: cents/kg
            Matcher centsMatcher = Pattern.compile("([0-9.]+)\\s*cents?/kg").matcher(rule);
            if (centsMatcher.find()) {
                System.out.println("规则2入参:" + centsMatcher.group(1));
                BigDecimal rate = new BigDecimal(centsMatcher.group(1))
                        .multiply(new BigDecimal("0.01")) // 美分转美元
                        .multiply(itemWeight)
                        .setScale(SCALE, ROUNDING_MODE);
                System.out.println("规则2输出结果:" + rate);
                totalTax = totalTax.add(rate);
                continue;
            }

            // 规则3: $/kg
            Matcher dollarMatcher = Pattern.compile("\\$([0-9.]+)\\s*/kg").matcher(rule);
            if (dollarMatcher.find()) {
                System.out.println("规则3入参:" + dollarMatcher.group(1));
                BigDecimal rate = new BigDecimal(dollarMatcher.group(1))
                        .multiply(itemWeight)
                        .setScale(SCALE, ROUNDING_MODE);
                System.out.println("规则3输出结果:" + rate);
                totalTax = totalTax.add(rate);
                continue;
            }

            // 规则4: 百分比
            Matcher percentMatcher = Pattern.compile("([0-9.]+)%").matcher(rule);
            if (percentMatcher.find()) {
                System.out.println("规则4入参:" + percentMatcher.group(1));
                BigDecimal percent = new BigDecimal(percentMatcher.group(1))
                        .divide(new BigDecimal("100"), 10, ROUNDING_MODE); // 百分比转换
                BigDecimal tax = itemValue.multiply(percent)
                        .setScale(8, ROUNDING_MODE);
                System.out.println("规则4输出结果:" + percent + " --------------- " + tax);
                totalTax = totalTax.add(tax);
                continue;
            }
            throw new RuntimeException("us Invalid tax rule: " + rule);
        }
        //System.out.println("AI calculate " + totalTax.toPlainString());
        return totalTax;
    }

    /**
     * 获取EUR的税值 (FR,DE,IT,ES)
     *
     * @param itemValue  申报价值
     * @param itemWeight 申报重量
     * @param usTaxMaps  税值列表
     * @return 税值
     */
    private static BigDecimal calculateEachItemTaxEur(BigDecimal itemValue, BigDecimal itemWeight, Map<String, String> usTaxMaps) {

        BigDecimal totalTax;
        AtomicReference<BigDecimal> taxZero = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> taxOne = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> taxTwo = new AtomicReference<>(BigDecimal.ZERO);

        usTaxMaps.forEach((key, value) -> {
            switch (key) {
                case "0":
                    taxZero.set(calculateEachItemTax2(itemValue, itemWeight, value));
                    break;
                case "1":
                    taxOne.set(calculateEachItemTax2(itemValue, itemWeight, value));
                    break;
                case "2":
                    taxTwo.set(calculateEachItemTax2(itemValue, itemWeight, value));
                    break;
                default:
                    throw new RuntimeException("Invalid tax type: " + key);

            }
        });
        if (taxTwo.get().compareTo(BigDecimal.ZERO) == 0) {
            totalTax = taxZero.get().add(taxOne.get());
        } else if (taxTwo.get().compareTo(taxZero.get()) > 0) {
            totalTax = taxOne.get().add(taxTwo.get());
        } else {
            totalTax = taxZero.get().add(taxOne.get());
        }
        return totalTax;
    }

}
